package csl.bluetooth.base;

import csl.bluetooth.tools.conn.ConnectTool;
import csl.bluetooth.tools.utils.MyUtils;
import csl.bluetooth.tools.utils.StringUtils;
import org.jb2011.lnf.beautyeye.BeautyEyeLNFHelper;

import javax.bluetooth.RemoteDevice;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.io.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.List;

/**
 * @author 陈少磊
 * @version 1.0.0
 * @ClassName BlueToothTools.java
 * @Description TODO
 * @createTime 2021年03月23日 18:11:00
 */
public class BlueToothTools extends JFrame {

    /**
     * 已写标签
     */
    public static ArrayList<String> isSetData = new ArrayList<>();


    /**
     * 未写标签
     */
    public static ArrayList<String> unSetData = new ArrayList<>();

    /**
     * 当前选中标签（已写）
     */
    private JPanel isTagList;

    /**
     * 当前选中标签（未写）
     */
    private JPanel unTagList;

    /**
     * 读取标签
     */
    private JButton open;

    /**
     * 执行结果
     */
    public static ArrayList<Byte> result = new ArrayList<>();

    private JScrollPane jScrollPane;

    private ReaderBase readerBase;

    private static final BluetoothClient client = new BluetoothClient();

    private List<Byte> selectTag;

    private final JLabel jLabel = new JLabel();

    private JFrame jf;

    private JPanel bleContent;

    private JPanel tagContent;

    private JPanel assetContent;

    private JPanel tagEditContent;

    /**
     * 窗体宽度
     */
    private int width;

    /**
     * 窗体高度
     */
    private int height;

    /**
     * 登录者部门编号
     */
    private String departNum;

//    public static void main(String[] args) {
//        new BlueToothTools("1");
//    }

    /**
     * 初始化界面
     *
     * @param departNum 接收登录者的部门编号
     */
    public BlueToothTools(String departNum) {
        try {
            //设置本属性将改变窗口边框样式定义
            BeautyEyeLNFHelper.frameBorderStyle = BeautyEyeLNFHelper.FrameBorderStyle.osLookAndFeelDecorated;
            org.jb2011.lnf.beautyeye.BeautyEyeLNFHelper.launchBeautyEyeLNF();
            UIManager.put("RootPane.setupButtonVisible", true);
        }
        catch(Exception e) {
            //TODO exception
        }
        this.departNum = departNum;
        init();
    }

    /**
     * 初始化页面
     */
    public void init() {
        EventQueue.invokeLater(() -> {
            jf = new JFrame();
            this.getContentPane().add(new JLabel("Just a test."));
            this.setUndecorated(true); // 去掉窗口的装饰
            this.getRootPane().setWindowDecorationStyle(JRootPane.NONE);//采用指定的窗口装饰风格
            Toolkit kit = Toolkit.getDefaultToolkit();
            Dimension screen = kit.getScreenSize();
            width = screen.width;
            height = screen.height;
            jf.setLocationByPlatform(true);
            jf.setBounds(0, 0, width, height);
            //frame icon
            Image img = new ImageIcon("resource/RFID-icon.png").getImage();
            jf.setIconImage(img);
            jf.setTitle("RFID标签读写系统"); //(太原工业学院使用者请关闭快速读写TID功能)
            jf.setFont(new Font("华文行楷",Font.ITALIC,22));
            jf.setResizable(false);
            jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            jf.setVisible(true);
            // log
            jLabel.setBounds(250, 730, 1500, 100);
            Font f = new Font("华文行楷", Font.ITALIC, 25);
            jLabel.setFont(f);
            jLabel.setForeground(Color.BLUE);
            jf.add(jLabel);
//          菜单栏
            JMenuBar menuBar = new JMenuBar();
            jf.setJMenuBar(menuBar);
//            蓝牙操作
            JMenu bleEdit = new JMenu("蓝牙操作");
            bleEdit.setFont(new Font("华文行楷",Font.ITALIC,22));
            menuBar.add(bleEdit);
//            蓝牙搜索界面
            bleContent = new JPanel();
            bleContent.setBounds(0, 0, width - width / 2, height - height / 2);
            bleContent.setVisible(false);
            jf.add(bleContent);
//            标签操作界面
            GridLayout g = new GridLayout(1,1);
            tagContent = new JPanel(g);
            tagContent.setBounds(0, 0, width - width / 2, height - height / 2);
            tagContent.setVisible(false);
            jf.add(tagContent);

//            资产列表
            assetContent = new JPanel();
            assetContent.setBorder(BorderFactory.createTitledBorder(BorderFactory.createTitledBorder(""),"资产列表",TitledBorder.CENTER,TitledBorder.TOP,new Font("宋体",Font.BOLD,22)));

            assetContent.setPreferredSize(new Dimension(width , height - height / 5));
            assetContent.setVisible(true);
            tagContent.add("资产列表", assetContent);

//            标签列表
            tagEditContent = new JPanel();
            tagEditContent.setBorder(BorderFactory.createTitledBorder(BorderFactory.createTitledBorder(""),"标签操作",TitledBorder.CENTER,TitledBorder.TOP,new Font("宋体",Font.BOLD,22)));
            tagEditContent.setVisible(true);
            tagContent.add("标签操作", tagEditContent);

            JMenuItem scanBle = new JMenuItem("搜索蓝牙设备");
            scanBle.setFont(new Font("华文行楷",Font.ITALIC,22));
            scanBle.addActionListener(event -> {
                jLabel.setText("正在搜索附近蓝牙设备...");
                bleContent.removeAll();
                new Thread(() -> {
                    try {
                        scanDevices(bleContent);
                        jLabel.setText("搜索蓝牙设备结束！");
                    } catch (IOException | InterruptedException e) {
                        e.printStackTrace();
                    }
                }).start();
            });
            bleEdit.add(scanBle);
            bleEdit.addSeparator();

//            标签操作
            JMenu tagEdit = new JMenu("标签操作");
            tagEdit.setFont(new Font("华文行楷",Font.ITALIC,22));

            JMenuItem tag = new JMenuItem("数据读写");
            tag.setFont(new Font("华文行楷",Font.ITALIC,22));
            tag.addActionListener(event -> {
                tagEditContent.removeAll();
                tagEditContent.revalidate();
                tagEditContent.updateUI();
                bleContent.setVisible(false);
                tagContent.setVisible(true);
                new Thread(() -> {
                    open = new JButton("识别标签");
                    open.setPreferredSize(new Dimension(tagEditContent.getWidth()-tagEditContent.getWidth()/9, 30));
                    open.setFont(new Font("微软雅黑", Font.BOLD, 15));
                    open.setVisible(true);
//                    开始扫描
                    open.addActionListener(e -> {
                        closeTid();
                        isTagList.removeAll();
                        isTagList.updateUI();
                        unTagList.removeAll();
                        unTagList.updateUI();
                        isSetData.clear();
                        unSetData.clear();
                        if (readerBase==null){
                            jLabel.setText("请连接蓝牙！");
                            return;
                        }
                        try {
                            jLabel.setText("正在读取标签...");
                            readerBase.realTimeInventory((byte) -1, (byte) 1);
                            Thread.sleep(1000);
                        } catch (InterruptedException interruptedException) {
                            jLabel.setText("读取异常！");
                        }
                        if (isSetData.isEmpty() && unSetData.isEmpty()){
                            this.jLabel.setText("未识别到标签，请重新识别");
                        }else{
                            if (!isSetData.isEmpty() && unSetData.isEmpty()){
                                if (isSelect(isSetData.get(0))){
                                    flushedSetAndUnSet();
                                    this.jLabel.setText("选中标签："+StringUtils.toAssetNum(isSetData.get(0)));
                                }
                            }
                            if (!unSetData.isEmpty() && isSetData.isEmpty()){
                                if (isSelect(unSetData.get(0))){
                                    flushedSetAndUnSet();
                                    this.jLabel.setText("选中标签："+StringUtils.toAssetNum(unSetData.get(0)));
                                }
                            }

                        }
                    });
                    tagEditContent.add(open);
                    JLabel powerLabel = new JLabel("频率值:");
                    powerLabel.setFont(new Font("微软雅黑", Font.BOLD, 17));
                    tagEditContent.add(powerLabel);
                    JTextArea powerNum = new JTextArea() {
                        @Override
                        public Dimension getPreferredSize() {
                            return new Dimension(100,30);
                        }
                    };
                    powerNum.setFont(new Font("微软雅黑", Font.BOLD, 17));
                    tagEditContent.add(powerNum);
                    JButton getPower = new JButton("读取频率");
                    JButton setPower = new JButton("设置频率");
                    getPower.addActionListener(e -> {
                        tagEditContent.revalidate();
                        result.clear();
                        if (readerBase==null){
                            jLabel.setText("请连接蓝牙！");
                            return;
                        }
                        readerBase.getOutputPower((byte) 1);
                        try {
                            jLabel.setText("正在获取频率...");
                            Thread.sleep(700);
                            if (result.isEmpty()){
                                System.out.println("[]");
                                jLabel.setText("获取频率失败！");
                            }else{
                                powerNum.setText(result.get(4).toString());
                                jLabel.setText("获取频率成功！");
                            }
                        } catch (InterruptedException interruptedException) {
                            interruptedException.printStackTrace();
                            jLabel.setText("获取频率异常！");
                        }
                    });
                    tagEditContent.add(getPower);
                    setPower.addActionListener(e->{
                        result.clear();
                        if (readerBase==null){
                            jLabel.setText("请连接蓝牙！");
                            return;
                        }
                        String value = powerNum.getText();
                        jLabel.setText("正在设置频率...");
                        try {
                            int power = Integer.parseInt(value);
                            readerBase.setOutputPower((byte) 1,(byte) power);
                            Thread.sleep(700);
                            if (result.isEmpty()){
                                jLabel.setText("频率设置失败！");
                            }else{
                                jLabel.setText("频率设置成功！");
                            }
                        }catch (Exception exception){
                            jLabel.setText("设置频率值异常！（频率值只能为数字）");
                        }

                    });
                    tagEditContent.add(setPower);

//                    识别到的标签
                    isTagList = new JPanel();
                    isTagList.setBorder(BorderFactory.createTitledBorder(BorderFactory.createTitledBorder(""),"当前选中标签(已写)",TitledBorder.CENTER,TitledBorder.TOP,new Font("宋体",Font.BOLD,22)));
                    isTagList.setPreferredSize(new Dimension(tagEditContent.getWidth()-tagEditContent.getWidth()/3, tagEditContent.getHeight()));
                    isTagList.setVisible(true);
//                    添加滚动条
                    JScrollPane readSelectJsc = new JScrollPane(isTagList){
                        @Override
                        public Dimension getPreferredSize() {
                            return new Dimension(tagEditContent .getWidth(), height / 3);
                        }
                    };
                    readSelectJsc.setVisible(true);
                    tagEditContent.add("当前选中标签(已写)", readSelectJsc);
                    tagEditContent.revalidate();
                    tagEditContent.revalidate();
                    //识别未写入标签
                    unTagList = new JPanel();
                    unTagList.setBorder(BorderFactory.createTitledBorder(BorderFactory.createTitledBorder(""),"当前选中标签(未写)",TitledBorder.CENTER,TitledBorder.TOP,new Font("宋体",Font.BOLD,22)));
                    unTagList.setPreferredSize(new Dimension(tagEditContent.getWidth()-tagEditContent.getWidth()/3, tagEditContent.getHeight()));
                    unTagList.setVisible(true);
//                    添加滚动条
                    JScrollPane unTag = new JScrollPane(unTagList){
                        @Override
                        public Dimension getPreferredSize() {
                            return new Dimension(tagEditContent .getWidth(), height / 3);
                        }
                    };
                    unTag.setVisible(true);
                    tagEditContent.add("当前选中标签(未写)", unTag);
                    tagEditContent.revalidate();
                }).start();
                new Thread(this::createDataList).start();
            });
            tagEdit.add(tag);
            menuBar.add(tagEdit);
//            帮助
            JMenu help = new JMenu("帮助");
            help.setFont(new Font("华文行楷",Font.ITALIC,22));

            JMenuItem about = new JMenuItem("如何使用");
            about.setFont(new Font("华文行楷",Font.ITALIC,22));

            about.addActionListener(event -> {
                tagContent.setVisible(false);
                bleContent.setVisible(true);
                bleContent.removeAll();
                JLabel use = new JLabel();
                use.setText("<html><body>蓝牙连接<br>" +
                        "1、开启电脑蓝牙功能;<br>" +
                        "2、进入RFID读写系统;<br>" +
                        "3、选中蓝牙操作并点击搜索蓝牙设备进行蓝牙搜索。<br>" +
                        "4、选中蓝牙目标进行点击实现蓝牙连接（再次点击即可断开连接）<br>" +
                        "标签操作<br>" +
                        "1、选中标签操作并点击标签读写进行数据初始化；<br>" +
                        "3、设置读取频率（可不设置-即采用设备默认频率）；<br>" +
                        "4、点击识别标签；<br>" +
                        "5、点击左侧资产编号即可实现标签写入。<br>"
                        +"</body></html>");
                use.setFont(new Font("宋体",Font.BOLD,30));
                use.setForeground(Color.BLUE);
                bleContent.add(use);
                bleContent.updateUI();
            });
            help.add(about);
            menuBar.add(help);

//            退出
            JMenu ex = new JMenu("退出");
            ex.setFont(new Font("华文行楷",Font.ITALIC,22));

            JMenuItem loginOut = new JMenuItem("注销");
            loginOut.setFont(new Font("华文行楷",Font.ITALIC,22));

            loginOut.addActionListener(event -> {
                System.out.println("退出登录");
                jf.dispose();
                new Login();
            });
            ex.add(loginOut);
//            关闭程序
            JMenuItem exit = new JMenuItem("关闭程序");
            exit.setFont(new Font("华文行楷",Font.ITALIC,22));

            exit.addActionListener(event -> {
                System.exit(0);
            });
            ex.add(exit);
            menuBar.add(ex);
        });
    }

    /**
     * 刷新标签列表
     */
    private void flushed(){
        isTagList.removeAll();
        isTagList.updateUI();
        unTagList.removeAll();
        unTagList.updateUI();
        isSetData.clear();
        unSetData.clear();
        if (readerBase==null){
            return;
        }
        try {
            readerBase.realTimeInventory((byte) -1, (byte) 1);
            Thread.sleep(1200);
        } catch (InterruptedException ignored) {
        }
        if (!isSetData.isEmpty() && unSetData.isEmpty()){
            if (isSelect(isSetData.get(0))){
                flushedSetAndUnSet();
            }
        }
        if (!unSetData.isEmpty() && isSetData.isEmpty()){
            if (isSelect(unSetData.get(0))){
                flushedSetAndUnSet();
            }
        }
        closeTid();
    }

    /**
     * 刷新选中
     */
    private void flushedSetAndUnSet(){
        isTagList.removeAll();
        unTagList.removeAll();
        for (String data : isSetData) {
            JButton jj = new JButton(StringUtils.toAssetNum(data));
            jj.setPreferredSize(new Dimension(isTagList.getWidth()-10,30));
            jj.setFont(new Font("微软雅黑", Font.BOLD, 15));
            jj.addActionListener(event1 -> {
                result.clear();
                isSetData.clear();
                isSetData.add(data);
                if (isSelect(isSetData.get(0))){
                    this.jLabel.setText("选中标签："+StringUtils.toAssetNum(isSetData.get(0)));
                }
            });
            isTagList.add(jj);
            isTagList.revalidate();
        }
        for (String data : unSetData){
            JButton jj = new JButton(StringUtils.toAssetNum(data));
            jj.setPreferredSize(new Dimension(isTagList.getWidth()-10,30));
            jj.setFont(new Font("微软雅黑", Font.BOLD, 15));
            jj.addActionListener(event1 -> {
                result.clear();
                unSetData.clear();
                unSetData.add(data);
                if (isSelect(unSetData.get(0))){
                    this.jLabel.setText("选中标签："+StringUtils.toAssetNum(unSetData.get(0)));
                }
            });
            unTagList.add(jj);
            unTagList.revalidate();
        }
    }

    /**
     * 选中标签
     * @param s 待处理数据
     * @return 返回资产编号
     */
    private boolean isSelect(String s) {
        byte[] bytes1 = StringUtils.hexStrToBytes(s);
        readerBase.setAccessEpcMatch((byte) 1, (byte) bytes1.length, bytes1);
        try {
            Thread.sleep(700);
            if(result.isEmpty()){
                System.out.println(result);
            }else{
                this.selectTag = result;
                System.out.println(result);
            }
        } catch (InterruptedException interruptedException) {
            jLabel.setText("选中"+s+"异常！");
            return false;
        }
        return true;
    }

    /**
     * 关闭TID
     */
    private void closeTid(){
        if (readerBase!=null) {
            try {
                readerBase.setImpinjFastTid((byte) 1, false, false);
                Thread.sleep(700);
            } catch (InterruptedException interruptedException) {
                closeTid();
            }
        }
    }

    /**
     * 修改标签后修改资产信息
     * @param setId 资产编号
     * @return 是否修改成功1-成功，-1失败
     */
    private void updateAsset(String setId) throws SQLException, ClassNotFoundException {
        ConnectTool connectTool = new ConnectTool();
        Connection conn = connectTool.getConn();
        PreparedStatement ps = conn.prepareStatement("update ias_asset set isRead = '1' where assetNum = ?");
        ps.setString(1,setId);
        ps.executeUpdate();
        connectTool.close();
    }

    /**
     * 创建资产信息表格
     */
    private void createDataList() {
        try {
            ConnectTool connectTool = new ConnectTool();
            Connection conn = connectTool.getConn();
            PreparedStatement ps = conn.prepareStatement("select * from ias_asset where departNum = ?");
            ps.setString(1, this.departNum);
            ResultSet res = ps.executeQuery();
            ArrayList<HashMap<String, String>> list = new ArrayList<>(12);
            if (res != null) {
                while (res.next()) {
                    HashMap<String, String> map = new HashMap<>(12);
                    map.put("assetNum", res.getString("assetNum"));
                    map.put("assetName", res.getString("assetName"));
                    map.put("assetModel", res.getString("assetModel"));
                    map.put("assetPrice", res.getString("assetPrice"));
                    map.put("assetFactory", res.getString("assetFactory"));
                    map.put("assetDocumentNum", res.getString("assetDocumentNum"));
                    map.put("assetBuyDate", res.getString("assetBuyDate"));
                    map.put("assetTakePeople", res.getString("assetTakePeople"));
                    map.put("assetRemrk", res.getString("assetRemrk"));
                    map.put("isRead", res.getString("isRead"));
                    list.add(map);
                }
            }
            // 生成的数据列表
            DefaultTableModel model = new DefaultTableModel();
            JPanel jp = new JPanel();
            //创建表头
            model.setColumnIdentifiers(new Object[]{"","资产编号", "资产名称", "资产类型规格", "厂家", "单据号", "购置日期", "领用人", "备注", "是否写入标签"});
            if (list.size() > 0) {
                for (HashMap<String, String> map : list) {
                    String assetNum = map.get("assetNum");
                    String assetName = map.get("assetName");
                    String assetModel = map.get("assetModel");
                    String assetFactory = map.get("assetFactory");
                    String assetDocumentNum = map.get("assetDocumentNum");
                    String assetBuyDate = map.get("assetBuyDate");
                    String assetTakePeople = map.get("assetTakePeople");
                    String assetRemrk = map.get("assetRemrk");
                    String isRead = map.get("isRead");
                    if ("0".equals(isRead)) {
                        isRead = "否";
                    } else {
                        isRead = "是";
                    }
                    model.addRow(new Object[]{assetNum,assetNum, assetName, assetModel, assetFactory, assetDocumentNum, assetBuyDate, assetTakePeople, assetRemrk, isRead});
                }
                JTable table = new JTable(model) {
                    /**
                     * 设置table不可编辑
                     * @return 不可编辑
                     */
                    @Override
                    public boolean isCellEditable(int row, int column) {
                        return false;
                    }
                };
                table.getColumnModel().getColumn(0).setPreferredWidth(10);
                table.getColumnModel().getColumn(1).setPreferredWidth(130);
                table.setFont(new Font("宋体小四", Font.ITALIC, 13));
                table.getColumnModel().getColumn(0).setCellRenderer(new TableCellRenderer() {

                    /**
                     * 添加复选框
                     * @return 返回复选框
                     */
                    @Override
                    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                        JRadioButton cr = new JRadioButton();
                        cr.setFont(new Font("宋体小四",Font.CENTER_BASELINE,12));
                        cr.addChangeListener(e -> {
                            new Thread(()->{
                                String tagId = model.getValueAt(row, 1).toString();
                                setTag(tagId);
                                flushed();
                            }).start();
                        });
                        cr.setSelected(isSelected);
                        cr.setHorizontalAlignment((int) 0.5);
                        return cr;
                    }
                });
//                    添加滚动条
                jScrollPane = new JScrollPane(table) {
                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(assetContent.getWidth(), height - height / 3);
                    }
                };
                assetContent.removeAll();
                assetContent.add(jScrollPane);
                assetContent.add(jp);
                assetContent.revalidate();
            }
            connectTool.close();
        } catch (SQLException | ClassNotFoundException throwables) {
            jLabel.setText("网络连接异常，请检查是否连接校内网！");
        }

    }

    /**
     * 写入标签
     * @param tagId id
     */
    private void setTag(String tagId){
        result.clear();
        if (readerBase==null){
            jLabel.setText("请连接蓝牙！");
            return;
        }
        if (tagId == null || tagId.trim().equals("") || tagId.length()==0) {
            jLabel.setText("未选中资产编号，请点击左侧复选框！");
            return;
        }
        if (this.selectTag == null) {
            jLabel.setText("未选中标签，请选中要修改的标签！");
            return;
        }
        byte btReadId = 1;
        byte[] btAryPassWord = {0, 0, 0, 0};
        byte btMemBank = 1;
        byte btWordAdd = 2;
        byte btWordCnt = 3;
        byte[] btAryData = MyUtils.setTagIdEdit(tagId);
        readerBase.writeTag(btReadId,btAryPassWord,btMemBank,btWordAdd,btWordCnt,btAryData);
        try {
            jLabel.setText("正在将"+tagId+"写入标签...");
            Thread.sleep(700);
            if (result.isEmpty()){
                jLabel.setText(tagId+"写入标签错误！");
            }else{
                updateAsset(tagId);
                jLabel.setText(tagId+"写入标签成功！");
            }
            this.selectTag.clear();
        } catch (InterruptedException | SQLException | ClassNotFoundException interruptedException) {
            jLabel.setText(tagId+"写入标签异常！");
        }
        createDataList();
    }

    /**
     * 扫描设备
     */
    public void scanDevices(JPanel jp) throws IOException, InterruptedException {
        Set<RemoteDevice> devices = RemoteDeviceDiscovery.getDevices();
        if (devices.size() > 0) {
            createButton(devices, jp);
        }
    }


    /**
     * 创建蓝牙设备按钮
     *
     * @param devices 附近的蓝牙设备
     * @param jp      jp
     * @throws IOException IO异常
     */
    public void createButton(Set<RemoteDevice> devices, JPanel jp) throws IOException {
        bleContent.removeAll();
        bleContent.setVisible(true);
        tagContent.setVisible(false);
        for (RemoteDevice device : devices) {
            JButton jb = new JButton(device.getFriendlyName(false));
            jb.setSize(200, 150);
            jb.addActionListener(event -> {
                new Thread(() -> {
                    try {
                        this.jLabel.setText("正在连接" + device.getFriendlyName(false));
                        String s = client.startClient(device);
                        System.out.println(client.dataInputStream + "==" + client.outputStream);
                        readerBase = new ReaderBase(client.dataInputStream, client.outputStream);
                        this.jLabel.setText(s);
                    } catch (IOException | InterruptedException e) {
                        e.printStackTrace();
                    }
                }).start();
            });
            jb.setVisible(true);
            jp.add(jb);
            jp.revalidate();
            bleContent.updateUI();
        }
    }
}
